package com.wbw.ssb.component;

import com.wbw.ssb.mbg.entity.Granary;
import com.wbw.ssb.mbg.entity.System;
import com.wbw.ssb.mbg.mapper.GranaryDynamicSqlSupport;
import com.wbw.ssb.mbg.mapper.GranaryMapper;
import com.wbw.ssb.mbg.mapper.SystemMapper;
import com.wbw.ssb.service.HumidityService;
import com.wbw.ssb.service.SmogService;
import com.wbw.ssb.service.TemperatureService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;

/**
 * 博文让我不要分开这些状态，如果是大型项目，随着项目业务发展会出现问题
 * 在本项目中，前端必须要写类似下面的代码，增加前端工作量，
 * 虽然不会出现问题但不代表我认可这样子做*/
@Component
@ServerEndpoint(value = "/granaryStatus")
public class GranaryExceptionTask {
    private static final AtomicInteger onlineCount = new AtomicInteger(0);

    private static final Map<String, Session> clients = new ConcurrentHashMap<>();

    @Autowired
    HumidityService humidityService;
    @Autowired
    SmogService smogService;
    @Autowired
    TemperatureService temperatureService;
    @Autowired
    GranaryMapper granaryMapper;
    @Autowired
    SystemMapper systemMapper;

    @OnOpen
    public void onOpen(Session session) {
        onlineCount.incrementAndGet();
        clients.put(session.getId(), session);
    }

    @OnClose
    public void onClose(Session session) {
        onlineCount.decrementAndGet(); // 在线数减1
        clients.remove(session.getId());
    }


    private void sendMessage(String message) {
        clients.forEach((key, session) -> session.getAsyncRemote().sendText(message));
    }

    @Scheduled(cron = "*/5 * * * * ?")
    private void granaryExceptionCheck() {
        List<Granary> granaryList = granaryMapper.select(c->c
                .where(GranaryDynamicSqlSupport.enable,isEqualTo(true)));
        System system = systemMapper.select(c->c.limit(1)).get(0);
        StringBuilder dataException = new StringBuilder();
        StringBuilder equipmentException = new StringBuilder();
        Double humidity;
        Double smog;
        Double temperature;
        for(Granary granary:granaryList){
            humidity = humidityService.getNow(granary.getNumber()).getHumidity();
            smog = smogService.getNow(granary.getNumber()).getSmog();
            temperature = temperatureService.getNow(granary.getNumber()).getTemperature();
            if (humidity == null){
                equipmentException.append("湿度传感器、");
            }
            else if (humidity > system.getHumidityAlarmThreshold()){
                dataException.append("湿度、");
            }
            if (smog == null){
                equipmentException.append("烟雾传感器、");
            }else if(smog > system.getSmogAlarmThreshold()){
                dataException.append("烟雾浓度、");
            }
            if (temperature==null){
                equipmentException.append("温度传感器、");
            }else if(temperature> system.getTemperatureAlarmThreshold()){
                dataException.append("温度、");
            }
            if (dataException.length()==0&&equipmentException.length()==0){
                granary.setStatus(true);
            }else if (dataException.length()>0){
                granary.setStatus(false);
                dataException.deleteCharAt(dataException.length()-1);
                sendMessage("粮仓"+granary.getNumber()+":"+granary.getName()+dataException+"参数异常！");
            }else if(equipmentException.length()>0){
                granary.setStatus(false);
                equipmentException.deleteCharAt(equipmentException.length()-1);
                sendMessage("粮仓"+granary.getNumber()+":"+granary.getName()+equipmentException+"设备异常！");
            }
            dataException.setLength(0);
            equipmentException.setLength(0);
            granaryMapper.updateByPrimaryKeySelective(granary);
        }

    }

    public void sendMessage(Session session, String message) throws IOException {
        if(session != null){
            session.getBasicRemote().sendText(message);
        }
    }

}
